/***************************************************************************
 *                                                                         *
 * Copyright (c) 2007 - 2009 Nuvoton Technology Corp. All rights reserved.*
 *                                                                         *
 ***************************************************************************/
 
/****************************************************************************
 * 
 * FILENAME
 *     NUC900_VPOST_SAMSUNG_80_16BIT.c
 *
 * VERSION
 *     0.1 
 *
 * DESCRIPTION
 *
 *
 *
 *
 * DATA STRUCTURES
 *     None
 *
 * FUNCTIONS
 *
 *
 *     
 * HISTORY
 *     2005.03.16		Created by Shih-Jen Lu
 *
 *
 * REMARK
 *     None
 *
 *
 **************************************************************************/
#include <stdio.h>
#include "wblib.h"
#include "NUC900_VPOST_Regs.h"
#include "NUC900_VPOST.h"
#ifdef	HAVE_SAMSUNG_80_16BIT

#ifdef ECOS
cyg_handle_t	vpost_int_handle;
cyg_interrupt	vpost_int_holder;
#endif


static void Delay(int nCnt)
{
	volatile int  loop;
	for (loop=0; loop<nCnt; loop++);
}

static UINT32 g_nScreenWidth;
static UINT32 g_nScreenHeight;
static BOOL g_powerup=FALSE;


INT vpostOSDInit_SAMSUNG_80_16BIT(POSDFORMATEX pOSDformatex)
{

    vpostSetOSDSrc(pOSDformatex->ucOSDSrcFormat);
    vpostSetOSDBuffer(pOSDformatex->pFrameBuffer);
    vpostOSDSetWindow(pOSDformatex->nXstart,pOSDformatex->nYstart,pOSDformatex->nOSDWidth,pOSDformatex->nOSDHeight);
    
    writew(REG_LCM_OSD_FBCTRL,0);//clear OSD STRIDE,FF setting
    if ((pOSDformatex->ucOSDSrcFormat==OSD_SRC_RGB888)||(pOSDformatex->ucOSDSrcFormat==OSD_SRC_RGB666))
    {
		
		writew(REG_LCM_OSD_FBCTRL,inpw(REG_LCM_OSD_FBCTRL) | (pOSDformatex->nImageWidth<<16) | pOSDformatex->nImageWidth); //OSDFF~OSD_STRIDE
    }
    else if (pOSDformatex->ucOSDSrcFormat==OSD_SRC_RGB332)
    {
    	writew(REG_LCM_OSD_FBCTRL,inpw(REG_LCM_OSD_FBCTRL) | ((pOSDformatex->nImageWidth/4)<<16) | (pOSDformatex->nImageWidth/4)); //OSDFF~OSD_STRIDE
    }
    else{
        writew(REG_LCM_OSD_FBCTRL,inpw(REG_LCM_OSD_FBCTRL) | ((pOSDformatex->nImageWidth/2)<<16) | (pOSDformatex->nImageWidth/2)); //OSDFF~OSD_STRIDE
    }
    vpostOSDScalingCtrl(1,0,0);
    vpostOSDSetOverlay(DISPLAY_OSD,DISPLAY_OSD,0,0,0);
        
    return 0;
}






static VOID vpostInitialFunction1(UINT8 ROT90)
{

	vpostLCDWriteAddr(0x01);
	vpostLCDWriteData(0x0115);
	
	vpostLCDWriteAddr(0x02);
	vpostLCDWriteData(0x0700);
	
	
	vpostLCDWriteAddr(0x05);
	if (ROT90==1)
	    vpostLCDWriteData(0x1028);				//k04264-1
	else
	    vpostLCDWriteData(0x1230);
	vpostLCDWriteAddr(0x06);
	vpostLCDWriteData(0x0000);
	vpostLCDWriteAddr(0x07);
	vpostLCDWriteData(0x0104);
	vpostLCDWriteAddr(0x0b);
	vpostLCDWriteData(0x0000);
}
static VOID vpostPowerSettingFunction()
{
	vpostLCDWriteAddr(0x0c);	
	vpostLCDWriteData(0x0000);	    
	vpostLCDWriteAddr(0x0d);	
	vpostLCDWriteData(0x0401);	    
	vpostLCDWriteAddr(0x0e);	
	vpostLCDWriteData(0x0d18);
	Delay(4000);
	vpostLCDWriteAddr(0x03);	
	vpostLCDWriteData(0x0214);	    
	vpostLCDWriteAddr(0x04);	
	vpostLCDWriteData(0x8000);	
	Delay(4000);	
	vpostLCDWriteAddr(0x0e);	
	vpostLCDWriteData(0x2910);	
	Delay(4000);
	vpostLCDWriteAddr(0x0d);	
	vpostLCDWriteData(0x0512);
}
static VOID vpostInitialFunction2()
{
	vpostLCDWriteAddr(0x21);	
	vpostLCDWriteData(0x0100);	    
	vpostLCDWriteAddr(0x30);	
	vpostLCDWriteData(0x0000);	    
	vpostLCDWriteAddr(0x31);	
	vpostLCDWriteData(0x0000);		
	vpostLCDWriteAddr(0x32);	
	vpostLCDWriteData(0x0000);		
	vpostLCDWriteAddr(0x33);	
	vpostLCDWriteData(0x0000);	    	
	vpostLCDWriteAddr(0x34);	
	vpostLCDWriteData(0x0000);	    
	vpostLCDWriteAddr(0x35);	
	vpostLCDWriteData(0x0707);		
	vpostLCDWriteAddr(0x36);	
	vpostLCDWriteData(0x0707);		
	vpostLCDWriteAddr(0x37);	
	vpostLCDWriteData(0x0000);		
	vpostLCDWriteAddr(0x0f);	
	vpostLCDWriteData(0x0000);	    	
	vpostLCDWriteAddr(0x11);	
	vpostLCDWriteData(0x0000);	    	
	vpostLCDWriteAddr(0x14);	
	vpostLCDWriteData(0x5c00);	    
	vpostLCDWriteAddr(0x15);	
	vpostLCDWriteData(0xa05d);		
	vpostLCDWriteAddr(0x16);	
	vpostLCDWriteData(0x7f00);		
	vpostLCDWriteAddr(0x17);	
	vpostLCDWriteData(0xA000);	    
	vpostLCDWriteAddr(0x3A);	
	vpostLCDWriteData(0x0000);	    
	vpostLCDWriteAddr(0x3B);	
	vpostLCDWriteData(0x0000);
}

static VOID vpostDisplayOnFunction(UINT8 ROT90)
{
	vpostLCDWriteAddr(0x07);	
	vpostLCDWriteData(0x0105);
	Delay(4000);
	vpostLCDWriteAddr(0x07);	
	vpostLCDWriteData(0x0125);	    
	vpostLCDWriteAddr(0x07);	
	vpostLCDWriteData(0x0127);	
	Delay(4000);
	vpostLCDWriteAddr(0x07);	
	vpostLCDWriteData(0x0137);	    
	vpostLCDWriteAddr(0x21);    
	vpostLCDWriteData(0x0000);		
	vpostLCDWriteAddr(0x22);
}

static VOID vpostSetCRTC_SAMSUNG_80_16BIT()
{   
	writew(REG_LCM_CRTC_SIZE,0x00a600c0); //CRTC_SIZE

	//writew(REG_LCM_CRTC_DEND,0x00a00080); //CRTC_DEND, a0 is bug on this panel
	writew(REG_LCM_CRTC_DEND,0x00a10080); //CRTC_DEND

	writew(REG_LCM_CRTC_HR,0x008f008a); //CRTC_HR

    writew(REG_LCM_CRTC_HSYNC,0x00bb00b6); //CRTC_HSYNC
	writew(REG_LCM_CRTC_VR,0x00a300a0); //CRTC_VR
    

}

VOID vpostSetup_SAMSUNG_80_16BIT(UINT8 ROT90)
{
	/* output-disable,video disable */
	writew(REG_LCM_DCCS,readw(REG_LCM_DCCS)& ~(VPOSTB_DISP_OUT_EN | VPOSTB_VA_EN));
	writew(REG_LCM_DCCS,readw(REG_LCM_DCCS) | VPOSTB_DISP_OUT_EN); //display_out-enable
	Delay(4000);
	vpostInitialFunction1(ROT90);
    vpostPowerSettingFunction();
    vpostInitialFunction2();
    Delay(4000); // add by smf
    vpostDisplayOnFunction(ROT90);
}

INT vpostLCMInit_SAMSUNG_80_16BIT(PLCDFORMATEX plcdformatex)
{
	UINT32 VA_FF;
	UINT32 VA_Sride;
    UINT32 nBytesPixel;
    if (g_powerup)
        return 0;
    
    outpw(REG_MFSEL,inpw(REG_MFSEL) | (3<<2));
	outpw(REG_CLKEN,inpw(REG_CLKEN) | 0x1);
    
    g_nScreenWidth = plcdformatex->nScreenWidth = 128;
	g_nScreenHeight = plcdformatex->nScreenHeight = 160;
	
	outpw(REG_LCM_DCCS,inpw(REG_LCM_DCCS) | VPOSTB_ENG_RST);
	Delay(100);
	outpw(REG_LCM_DCCS,inpw(REG_LCM_DCCS) & ~VPOSTB_ENG_RST);
	Delay(100);
	
	if ( (plcdformatex->ucVASrcFormat == VA_SRC_RGB888) || (plcdformatex->ucVASrcFormat == VA_SRC_RGB666))//4 BytesPixel
	{
	    nBytesPixel = 4;
	}
	else
	{
	    nBytesPixel = 2;
	}
	/* set the display buffer (fetch from VA_BADDR0, if at single buffer mode)*/
	if (vpostAllocVABuffer(plcdformatex,nBytesPixel)==FALSE)
		return ERR_NULL_BUF;
		
	/* set display mode */
	vpostSetDisplayMode(0);  // continue mode
	
	/* set display video source format */
	vpostSetVASrc(plcdformatex->ucVASrcFormat);
	/*
	if (ucVASrcType!=0)
		outpw(REG_LCM_DCCS,inpw(REG_LCM_DCCS) | ucVASrcType);
	else
		outpw(REG_LCM_DCCS,inpw(REG_LCM_DCCS) & ~(7<<8));
	*/
	//18-bit,256k,80mode,mpu-based,cmd18-16L0
	
	
	//vpostSetDeviceCtrl(_tSAMSUNG_80_16BIT);
	
	outpw(REG_LCM_DEV_CTRL,0x0);//clear register
	writew(REG_LCM_DEV_CTRL,inpw(REG_LCM_DEV_CTRL) | VPOSTB_CMDLOW 
												   | VPOSTB_CM16t18LOW
												   | VPOSTB_CMD16
												   | VPOSTB_DATA16or18 | VPOSTB_IM256K_8or16
												   | VPOSTB_MPU80
												   | VPOSTB_COLORTYPE_64K
												   | VPOSTB_DEVICE_MPU );
	
	

	if (plcdformatex->ucROT90)
		vpostSetCRTC_SAMSUNG_80_16BIT();// OR Hori=161 Ver=127
	else
		vpostSetCRTC_SAMSUNG_80_16BIT();
	
	/* set video stream frame buffer control */
	VA_FF = (plcdformatex->nScreenWidth)*(nBytesPixel)/4;//word unit
    VA_Sride = (plcdformatex->nScreenWidth)*(nBytesPixel)/4;//word unit
    outpw(REG_LCM_VA_FBCTRL,inpw(REG_LCM_VA_FBCTRL) &~0x7ff07ff | (VA_FF<<16) | VA_Sride);
    				
	vpostSetup_SAMSUNG_80_16BIT(plcdformatex->ucROT90);
	//outpw(0xb0008030,0x04000400);
#if 0	
	{
		int data,i;
		for (i=0;i<0xbf;i++)
		{
			vpostLCDWriteAddr(i);
			data = vpostLCDReadData();
			printf("reg %x = %x\n",i,data);
		}
	}
#endif	
	//vpostEnable_Int();
	
	vpostVAScalingCtrl(1,0,1,0,VA_SCALE_INTERPOLATION);  // add by smf
    vpostVAStartTrigger();   // add by smf
    
	return 0;
}



#endif	/* HAVE_SAMSUNG_80_18IT */